package com.qf.air.search.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.qf.air.search.entity.Air;
import com.qf.air.search.service.ElasticAirService;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

/**
 * @author 10537
 * @version V1.0
 * @Date 2021/11/4 10:01
 */
@Component
public class ElasticAirServiceImpl implements ElasticAirService {
    @Autowired
    private RestHighLevelClient client;
    private ObjectMapper mapper = new ObjectMapper();
    private String index = "air";



    @Override
    public void indexAir(Map air) throws IOException {
        String value = mapper.writeValueAsString(air);
        IndexRequest request=new IndexRequest();
        request.index("air");
        request.id(air.get("id").toString());
        request.source(value,XContentType.JSON);
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        if (!"CREATED".equalsIgnoreCase(response.getResult().getLowercase())) {
            throw new RuntimeException("添加文档失败");
        }
    }

    @Override
    //public SearchResponse searchAir(Integer page, Integer rows, Integer districtId, String monitoringStation, Date startTime, Date endTime) throws IOException {
    public SearchResponse searchAir(Map map) throws IOException {
        Integer page= (Integer) map.get("page");
        Integer rows= (Integer) map.get("rows");
        Integer districtId= (Integer) map.get("districtId");
        String monitoringStation= (String) map.get("monitoringStation");
        Date startTime= (Date) map.get("startTime");
        Date endTime= (Date) map.get("endTime");
        SearchRequest request=new SearchRequest();
        request.indices("air");

        SearchSourceBuilder ssb=new SearchSourceBuilder();
        BoolQueryBuilder boolQuery= QueryBuilders.boolQuery();

        if (districtId!=null&&districtId!=0){
            boolQuery.must(QueryBuilders.matchQuery("districtId",districtId));
        }
        if (monitoringStation!=null&&!"".equals(monitoringStation)){
            boolQuery.must(QueryBuilders.matchQuery("monitoringStation",monitoringStation));
        }
        if (startTime!=null){
            boolQuery.must(QueryBuilders.rangeQuery("monitorTime").from(startTime));
        }
        if (endTime!=null){
            boolQuery.must(QueryBuilders.rangeQuery("monitorTime").to(endTime));
        }
        ssb.query(boolQuery);
        ssb.from(page);
        ssb.size(rows);
        ssb.sort("id", SortOrder.ASC);
        HighlightBuilder highlightBuilder=new HighlightBuilder();
        highlightBuilder.fragmentSize(2);
        highlightBuilder.preTags("<span style='color:red;'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.field("monitoringStation");
        ssb.highlighter(highlightBuilder);


        request.source(ssb);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        return response;
    }

    @Override
    public void deleteAir(Integer id) {
        DeleteRequest request=new DeleteRequest();
        request.index("air");
        request.id(id.toString());
        DeleteResponse delete = null;
        try {
            delete = client.delete(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException("es数据删除失败");
        }
        if (!"deleted".equalsIgnoreCase(delete.getResult().getLowercase())){
            throw new RuntimeException("es数据删除失败");
        }
    }

    /**
     * 更新es当中的数据
     *
     * @param air
     */
    @Override
    public void updateAir(Map air) throws IOException {
        UpdateRequest request = new UpdateRequest();
        request.index("air");
        String value = mapper.writeValueAsString(air);
        request.id(air.get("id").toString());
        request.doc(value,XContentType.JSON);
        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
        if (!"updated".equalsIgnoreCase(update.getResult().getLowercase())){
            throw new RuntimeException("es数据更新失败");
        }

    }

    @Override
    public List<Map> getDistrictNameEcharts() throws IOException {
        SearchRequest request = new SearchRequest();
        request.indices("air");
        SearchSourceBuilder ssb = new SearchSourceBuilder();
        ssb.aggregation(AggregationBuilders.terms("districtName").field("districtName").size(10));
        ssb.size(0);
        request.source(ssb);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        Terms terms = response.getAggregations().get("districtName");
        List<Map> list = new ArrayList<>();
        for (Terms.Bucket bucket : terms.getBuckets()) {
            Map map = new HashMap();
            map.put("name", bucket.getKey());
            map.put("value", bucket.getDocCount());
            list.add(map);
        }
        return list;
    }

}
